﻿using System.Collections.Generic;
using log4net;
using MySql.Data.MySqlClient;

namespace Possan.MySQL.Providers
{
	class UserCache
	{
		private string _connStr;
		private string _usertablename;
		private string _membershiptablename;
		private static object _lockobject = new object();
		private static Dictionary<string, string> _idcache = new Dictionary<string, string>();
		private static Dictionary<string, string> _usernamecache = new Dictionary<string, string>();
		private ILog _log = LogManager.GetLogger(typeof(UserCache));

		public UserCache(string connectionstring)
		{
			_connStr = connectionstring;
			_usertablename = "aspnet_users";
			_membershiptablename = "aspnet_membership";
		}

		public string GetIdByUsername(string username)
		{
			string ret = "";

			lock (_lockobject)
			{
				if (_idcache.ContainsKey(username))
					ret = _idcache[username];
			}

			if (ret != "")
				return ret;

			_log.Debug("Loading userid for username \"" + username + "\"");

			using (var conn = new MySqlConnection(_connStr))
			{
				conn.Open();
				using (var cmd = conn.CreateCommand())
				{
					cmd.CommandText = "SELECT u.UserId FROM " + _usertablename + " u where u.LoweredUsername = @a";
					cmd.Parameters.Add(new MySqlParameter("@a", username.ToLower()));
					using (var rdr = cmd.ExecuteReader())
					{
						if (rdr.Read())
							ret = rdr["UserId"].ToString();

						rdr.Close();
					}
				}
				conn.Close();
			}

			if (ret != "")
				lock (_lockobject)
				{
					if (_idcache.ContainsKey(username))
						_idcache[username] = ret;
					else
						_idcache.Add(username, ret);
				}

			return ret;
		}






		public string GetUsernameByEmail(string email)
		{
			string ret = "";

			lock (_lockobject)
			{
				if (_usernamecache.ContainsKey(email))
					ret = _usernamecache[email];
			}

			if (ret != "")
				return ret;

			_log.Debug("Loading username for email \"" + email + "\"");

			using (var conn = new MySqlConnection(_connStr))
			{
				conn.Open();
				using (var cmd = conn.CreateCommand())
				{
					cmd.CommandText = @"select u.username
						from " + _usertablename + @" u
						inner join " + _membershiptablename + @" m on m.UserId = u.UserId
						where m.email = @a";

					cmd.Parameters.Add(new MySqlParameter("@a", email));
					using (MySqlDataReader rdr = cmd.ExecuteReader())
					{
						if (rdr.Read())
						{
							ret = (string)rdr["username"];
						}
						rdr.Close();
					}
					cmd.Dispose();
				}
				conn.Close();
			}

			if (ret != "")
				lock (_lockobject)
				{
					if (_usernamecache.ContainsKey(email))
						_usernamecache[email] = ret;
					else
						_usernamecache.Add(email, ret);
				}

			return ret;
		}
	}
}
